home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / comm.jar / content / navigator / navigator.js < prev    next >
Encoding:
Text File  |  2003-01-09  |  56.5 KB  |  1,762 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Netscape Public License
  6.  * Version 1.1 (the "License"); you may not use this file except in
  7.  * compliance with the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/NPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1998
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Blake Ross <blakeross@telocity.com>
  24.  *   Peter Annema <disttsc@bart.nl>
  25.  *
  26.  * Alternatively, the contents of this file may be used under the terms of
  27.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  28.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29.  * in which case the provisions of the GPL or the LGPL are applicable instead
  30.  * of those above. If you wish to allow use of your version of this file only
  31.  * under the terms of either the GPL or the LGPL, and not to allow others to
  32.  * use your version of this file under the terms of the NPL, indicate your
  33.  * decision by deleting the provisions above and replace them with the notice
  34.  * and other provisions required by the GPL or the LGPL. If you do not delete
  35.  * the provisions above, a recipient may use your version of this file under
  36.  * the terms of any one of the NPL, the GPL or the LGPL.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. const XREMOTESERVICE_CONTRACTID = "@mozilla.org/browser/xremoteservice;1";
  41. var gURLBar = null;
  42. var gProxyButton = null;
  43. var gProxyFavIcon = null;
  44. var gProxyDeck = null;
  45. var gBookmarksService = null;
  46. var gSearchService = null;
  47. var gNavigatorBundle;
  48. var gBrandBundle;
  49. var gNavigatorRegionBundle;
  50. var gBrandRegionBundle;
  51. var gLastValidURLStr = "";
  52. var gLastValidURL = null;
  53. var gHaveUpdatedToolbarState = false;
  54. var gClickSelectsAll = -1;
  55.  
  56. var pref = null;
  57.  
  58. var appCore = null;
  59.  
  60. //cached elements
  61. var gBrowser = null;
  62.  
  63. // focused frame URL
  64. var gFocusedURL = null;
  65. var gFocusedDocument = null;
  66.  
  67. // Pref listener constants
  68. const gButtonPrefListener =
  69. {
  70.   domain: "browser.toolbars.showbutton",
  71.   observe: function(subject, topic, prefName)
  72.   {
  73.     // verify that we're changing a button pref
  74.     if (topic != "nsPref:changed")
  75.       return;
  76.  
  77.     var buttonName = prefName.substr(this.domain.length+1);
  78.     var buttonId = buttonName + "-button";
  79.     var button = document.getElementById(buttonId);
  80.  
  81.     // We need to explicitly set "hidden" to "false"
  82.     // in order for persistence to work correctly
  83.     var show = pref.getBoolPref(prefName);
  84.     if (show)
  85.       button.setAttribute("hidden","false");
  86.     else
  87.       button.setAttribute("hidden", "true");
  88.  
  89.     // If all buttons before the separator are hidden, also hide the separator
  90.     if (allLeftButtonsAreHidden())
  91.       document.getElementById("home-bm-separator").setAttribute("hidden", "true");
  92.     else
  93.       document.getElementById("home-bm-separator").removeAttribute("hidden");
  94.   }
  95. };
  96.  
  97. const gTabStripPrefListener =
  98. {
  99.   domain: "browser.tabs.autoHide",
  100.   observe: function(subject, topic, prefName)
  101.   {
  102.     // verify that we're changing the tab browser strip auto hide pref
  103.     if (topic != "nsPref:changed")
  104.       return;
  105.  
  106.     var stripVisibility = !pref.getBoolPref(prefName);
  107.     if (gBrowser.mTabContainer.childNodes.length == 1)
  108.       gBrowser.setStripVisibilityTo(stripVisibility);
  109.   }
  110. };
  111.  
  112. /**
  113. * Pref listener handler functions.
  114. * Both functions assume that observer.domain is set to
  115. * the pref domain we want to start/stop listening to.
  116. */
  117. function addPrefListener(observer)
  118. {
  119.   try {
  120.     var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  121.     pbi.addObserver(observer.domain, observer, false);
  122.   } catch(ex) {
  123.     dump("Failed to observe prefs: " + ex + "\n");
  124.   }
  125. }
  126.  
  127. function removePrefListener(observer)
  128. {
  129.   try {
  130.     var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  131.     pbi.removeObserver(observer.domain, observer);
  132.   } catch(ex) {
  133.     dump("Failed to remove pref observer: " + ex + "\n");
  134.   }
  135. }
  136.  
  137. /**
  138. * We can avoid adding multiple load event listeners and save some time by adding
  139. * one listener that calls all real handlers.
  140. */
  141.  
  142. function loadEventHandlers(event)
  143. {
  144.   // Filter out events that are not about the document load we are interested in
  145.   if (event.originalTarget == _content.document) {
  146.     UpdateBookmarksLastVisitedDate(event);
  147.     UpdateInternetSearchResults(event);
  148.     checkForDirectoryListing();
  149.     postURLToNativeWidget();
  150.   }
  151. }
  152.  
  153. /**
  154.  * Determine whether or not the content area is displaying a page with frames,
  155.  * and if so, toggle the display of the 'save frame as' menu item.
  156.  **/
  157. function getContentAreaFrameCount()
  158. {
  159.   var saveFrameItem = document.getElementById("savepage");
  160.   if (!_content.frames.length || !isDocumentFrame(document.commandDispatcher.focusedWindow))
  161.     saveFrameItem.setAttribute("hidden", "true");
  162.   else
  163.     saveFrameItem.removeAttribute("hidden");
  164. }
  165.  
  166. // When a content area frame is focused, update the focused frame URL
  167. function contentAreaFrameFocus()
  168. {
  169.   var focusedWindow = document.commandDispatcher.focusedWindow;
  170.   if (isDocumentFrame(focusedWindow)) {
  171.     gFocusedURL = focusedWindow.location.href;
  172.     gFocusedDocument = focusedWindow.document;
  173.   }
  174. }
  175.  
  176. //////////////////////////////// BOOKMARKS ////////////////////////////////////
  177.  
  178. function UpdateBookmarksLastVisitedDate(event)
  179. {
  180.   var url = getWebNavigation().currentURI.spec;
  181.   if (url) {
  182.     // if the URL is bookmarked, update its "Last Visited" date
  183.     if (!gBookmarksService)
  184.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  185.                                     .getService(Components.interfaces.nsIBookmarksService);
  186.  
  187.     gBookmarksService.updateLastVisitedDate(url, _content.document.characterSet);
  188.   }
  189. }
  190.  
  191. function HandleBookmarkIcon(iconURL, addFlag)
  192. {
  193.   var url = getWebNavigation().currentURI.spec
  194.   if (url) {
  195.     // update URL with new icon reference
  196.     if (!gBookmarksService)
  197.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  198.                                     .getService(Components.interfaces.nsIBookmarksService);
  199.     if (addFlag)    gBookmarksService.updateBookmarkIcon(url, iconURL);
  200.     else            gBookmarksService.removeBookmarkIcon(url, iconURL);
  201.   }
  202. }
  203.  
  204. function UpdateInternetSearchResults(event)
  205. {
  206.   var url = getWebNavigation().currentURI.spec;
  207.   if (url) {
  208.     try {
  209.       var autoOpenSearchPanel =
  210.         pref.getBoolPref("browser.search.opensidebarsearchpanel");
  211.  
  212.       if (autoOpenSearchPanel || isSearchPanelOpen())
  213.       {
  214.         if (!gSearchService)
  215.           gSearchService = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
  216.                                          .getService(Components.interfaces.nsIInternetSearchService);
  217.  
  218.         var searchInProgressFlag = gSearchService.FindInternetSearchResults(url);
  219.  
  220.         if (searchInProgressFlag) {
  221.           if (autoOpenSearchPanel)
  222.             RevealSearchPanel();
  223.         }
  224.       }
  225.     } catch (ex) {
  226.     }
  227.   }
  228. }
  229.  
  230. function getBrowser()
  231. {
  232.   if (!gBrowser)
  233.     gBrowser = document.getElementById("content");
  234.   return gBrowser;
  235. }
  236.  
  237. function getHomePage()
  238. {
  239.   var url;
  240.   try {
  241.     url = pref.getComplexValue("browser.startup.homepage",
  242.                                Components.interfaces.nsIPrefLocalizedString).data;
  243.   } catch (e) {
  244.   }
  245.  
  246.   // use this if we can't find the pref
  247.   if (!url)
  248.     url = gNavigatorRegionBundle.getString("homePageDefault");
  249.  
  250.   // [ghzil] {
  251.   try {
  252.      pref.setCharPref("browser.startup.homepage", "chrome://help/content/welcome_top.html");
  253.   } catch (e) {}
  254.   // } [ghzil]
  255.  
  256.   return url;
  257. }
  258.  
  259. function UpdateBackForwardButtons()
  260. {
  261.   var backBroadcaster = document.getElementById("canGoBack");
  262.   var forwardBroadcaster = document.getElementById("canGoForward");
  263.   var webNavigation = getWebNavigation();
  264.  
  265.   // Avoid setting attributes on broadcasters if the value hasn't changed!
  266.   // Remember, guys, setting attributes on elements is expensive!  They
  267.   // get inherited into anonymous content, broadcast to other widgets, etc.!
  268.   // Don't do it if the value hasn't changed! - dwh
  269.  
  270.   var backDisabled = backBroadcaster.hasAttribute("disabled");
  271.   var forwardDisabled = forwardBroadcaster.hasAttribute("disabled");
  272.   if (backDisabled == webNavigation.canGoBack) {
  273.     if (backDisabled)
  274.       backBroadcaster.removeAttribute("disabled");
  275.     else
  276.       backBroadcaster.setAttribute("disabled", true);
  277.   }
  278.   if (forwardDisabled == webNavigation.canGoForward) {
  279.     if (forwardDisabled)
  280.       forwardBroadcaster.removeAttribute("disabled");
  281.     else
  282.       forwardBroadcaster.setAttribute("disabled", true);
  283.   }
  284. }
  285.  
  286. // Function allLeftButtonsAreHidden
  287. // Returns true if all the buttons left of the separator in the personal
  288. // toolbar are hidden, false otherwise.
  289. // Used by nsButtonPrefListener to hide the separator if needed
  290. function allLeftButtonsAreHidden()
  291. {
  292.   var buttonNode = document.getElementById("PersonalToolbar").firstChild;
  293.   while(buttonNode.tagName != "toolbarseparator") {
  294.     if(!buttonNode.hasAttribute("hidden") || buttonNode.getAttribute("hidden") == "false")
  295.       return false;
  296.     buttonNode = buttonNode.nextSibling;
  297.   }
  298.   return true;
  299. }
  300.  
  301. function Startup()
  302. {
  303.   // init globals
  304.   gNavigatorBundle = document.getElementById("bundle_navigator");
  305.   gBrandBundle = document.getElementById("bundle_brand");
  306.   gNavigatorRegionBundle = document.getElementById("bundle_navigator_region");
  307.   gBrandRegionBundle = document.getElementById("bundle_brand_region");
  308.  
  309.   gBrowser = document.getElementById("content");
  310.   gURLBar = document.getElementById("urlbar");
  311.  
  312.   SetPageProxyState("invalid", null);
  313.  
  314.   var webNavigation;
  315.   try {
  316.     // Create the browser instance component.
  317.     appCore = Components.classes["@mozilla.org/appshell/component/browser/instance;1"]
  318.                         .createInstance(Components.interfaces.nsIBrowserInstance);
  319.     if (!appCore)
  320.       throw "couldn't create a browser instance";
  321.  
  322.     // Get the preferences service
  323.     var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  324.                                 .getService(Components.interfaces.nsIPrefService);
  325.     pref = prefService.getBranch(null);
  326.  
  327.     webNavigation = getWebNavigation();
  328.     if (!webNavigation)
  329.       throw "no XBL binding for browser";
  330.   } catch (e) {
  331.     alert("Error launching browser window:" + e);
  332.     window.close(); // Give up.
  333.     return;
  334.   }
  335.  
  336.   // Do all UI building here:
  337.  
  338.   // set home button tooltip text
  339.   var homePage = getHomePage();
  340.   if (homePage)
  341.     document.getElementById("home-button").setAttribute("tooltiptext", homePage);
  342.  
  343.   // initialize observers and listeners
  344.   window.XULBrowserWindow = new nsBrowserStatusHandler();
  345.  
  346.   addPrefListener(gButtonPrefListener);
  347.   addPrefListener(gTabStripPrefListener);
  348.  
  349.   window.browserContentListener =
  350.     new nsBrowserContentListener(window, getBrowser());
  351.  
  352.   // Initialize browser instance..
  353.   appCore.setWebShellWindow(window);
  354.  
  355.   // Add a capturing event listener to the content area
  356.   // (rjc note: not the entire window, otherwise we'll get sidebar pane loads too!)
  357.   //  so we'll be notified when onloads complete.
  358.   var contentArea = document.getElementById("appcontent");
  359.   contentArea.addEventListener("load", loadEventHandlers, true);
  360.   contentArea.addEventListener("focus", contentAreaFrameFocus, true);
  361.  
  362.   var turboMode = false;
  363.   // set default character set if provided
  364.   if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
  365.     if (window.arguments[1].indexOf("charset=") != -1) {
  366.       var arrayArgComponents = window.arguments[1].split("=");
  367.       if (arrayArgComponents) {
  368.         //we should "inherit" the charset menu setting in a new window
  369.         getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
  370.       }
  371.     } else if (window.arguments[1].indexOf("turbo=yes") != -1) {
  372.       turboMode = true;
  373.     }
  374.   }
  375.  
  376.   //initConsoleListener();
  377.  
  378.   // XXXjag work-around for bug 113076
  379.   // there's another bug where we throw an exception when getting
  380.   // sessionHistory if it is null, which I'm exploiting here to
  381.   // detect the situation described in bug 113076.
  382.   // The same problem caused bug 139522, also worked around below.
  383.   try {
  384.     getBrowser().sessionHistory;
  385.   } catch (e) {
  386.     // sessionHistory wasn't set from the browser's constructor
  387.     // so we'll just have to set it here.
  388.  
  389.     // Wire up session and global history before any possible
  390.     // progress notifications for back/forward button updating
  391.     webNavigation.sessionHistory = Components.classes["@mozilla.org/browser/shistory;1"]
  392.                                              .createInstance(Components.interfaces.nsISHistory);
  393.  
  394.     // wire up global history.  the same applies here.
  395.     var globalHistory = Components.classes["@mozilla.org/browser/global-history;1"]
  396.                                   .getService(Components.interfaces.nsIGlobalHistory);
  397.     getBrowser().docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).globalHistory = globalHistory;
  398.  
  399.     const selectedBrowser = getBrowser().selectedBrowser;
  400.     if (selectedBrowser.securityUI)
  401.       selectedBrowser.securityUI.init(selectedBrowser.contentWindow);
  402.   }
  403.  
  404.   // hook up UI through progress listener
  405.   getBrowser().addProgressListener(window.XULBrowserWindow, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  406.  
  407.   // load appropriate initial page from commandline
  408.   var isPageCycling = false;
  409.  
  410.   // page cycling for tinderbox tests
  411.   if (!appCore.cmdLineURLUsed)
  412.     isPageCycling = appCore.startPageCycler();
  413.  
  414.   // only load url passed in when we're not page cycling
  415.   if (!isPageCycling) {
  416.     var uriToLoad;
  417.  
  418.     // Check for window.arguments[0]. If present, use that for uriToLoad.
  419.     if ("arguments" in window && window.arguments.length >= 1 && window.arguments[0])
  420.       uriToLoad = window.arguments[0];
  421.  
  422.     if (uriToLoad && uriToLoad != "about:blank") {
  423.       gURLBar.value = uriToLoad;
  424.       if ("arguments" in window && window.arguments.length >= 4) {
  425.         loadURI(uriToLoad, window.arguments[3]);
  426.       } else {
  427.         loadURI(uriToLoad);
  428.       }
  429.     }
  430.  
  431.     // Close the window now, if it's for turbo mode startup.
  432.     if ( turboMode ) {
  433.         // Set "command line used" flag.  If we don't do this, then when a cmd line url
  434.         // for a "real* invocation comes in, we will override it with the "cmd line url"
  435.         // from the turbo-mode process (i.e., the home page).
  436.         appCore.cmdLineURLUsed = true;
  437.         // For some reason, window.close() directly doesn't work, so do it in the future.
  438.         window.setTimeout( "window.close()", 100 );
  439.         return;
  440.     }
  441.  
  442.     const navBar = document.getElementById("nav-bar");
  443.     // Focus the content area unless we're loading a blank page
  444.     if ((!uriToLoad || uriToLoad == "about:blank") && !navBar.hidden && window.locationbar.visible)
  445.       setTimeout(WindowFocusTimerCallback, 0, gURLBar);
  446.     else
  447.       setTimeout(WindowFocusTimerCallback, 0, _content);
  448.  
  449.     // Perform default browser checking (after window opens).
  450.     setTimeout( checkForDefaultBrowser, 0 );
  451.  
  452.     // hook up remote support
  453.     if (XREMOTESERVICE_CONTRACTID in Components.classes) {
  454.       var remoteService;
  455.       remoteService = Components.classes[XREMOTESERVICE_CONTRACTID]
  456.                                 .getService(Components.interfaces.nsIXRemoteService);
  457.       remoteService.addBrowserInstance(window);
  458.     }
  459.   }
  460.  
  461.   // called when we go into full screen, even if it is
  462.   // initiated by a web page script
  463.   addEventListener("fullscreen", onFullScreen, false);
  464.  
  465.   // now load bookmarks after a delay
  466.   setTimeout(LoadBookmarksCallback, 0);
  467.  
  468. }
  469.  
  470. function LoadBookmarksCallback()
  471. {
  472.   try {
  473.     if (!gBookmarksService)
  474.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  475.                                     .getService(Components.interfaces.nsIBookmarksService);
  476.     gBookmarksService.ReadBookmarks();
  477.     // tickle personal toolbar to load personal toolbar items
  478.     var personalToolbar = document.getElementById("innermostBox");
  479.     personalToolbar.builder.rebuild();
  480.   } catch (e) {
  481.   }
  482. }
  483.  
  484. function WindowFocusTimerCallback(element)
  485. {
  486.   // This fuction is a redo of the fix for jag bug 91884
  487.   var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  488.                      .getService(Components.interfaces.nsIWindowWatcher);
  489.   if (window == ww.activeWindow) {
  490.     element.focus();
  491.   } else {
  492.     // set the element in command dispatcher so focus will restore properly
  493.     // when the window does become active
  494.     if (element instanceof Components.interfaces.nsIDOMElement)
  495.       document.commandDispatcher.focusedElement = element;
  496.     else if (element instanceof Components.interfaces.nsIDOMWindow)
  497.       document.commandDispatcher.focusedWindow = element;
  498.   }
  499. }
  500.  
  501. function BrowserFlushBookmarksAndHistory()
  502. {
  503.   // Flush bookmarks and history (used when window closes or is cached).
  504.   try {
  505.     // If bookmarks are dirty, flush 'em to disk
  506.     var bmks = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  507.                          .getService(Components.interfaces.nsIRDFRemoteDataSource);
  508.     bmks.Flush();
  509.  
  510.     // give history a chance at flushing to disk also
  511.     var history = Components.classes["@mozilla.org/browser/global-history;1"]
  512.                             .getService(Components.interfaces.nsIRDFRemoteDataSource);
  513.     history.Flush();
  514.   } catch(ex) {
  515.   }
  516. }
  517.  
  518. function Shutdown()
  519. {
  520.   // remove remote support
  521.   if (XREMOTESERVICE_CONTRACTID in Components.classes) {
  522.     var remoteService;
  523.     remoteService = Components.classes[XREMOTESERVICE_CONTRACTID]
  524.                               .getService(Components.interfaces.nsIXRemoteService);
  525.     remoteService.removeBrowserInstance(window);
  526.   }
  527.  
  528.   try {
  529.     getBrowser().removeProgressListener(window.XULBrowserWindow);
  530.   } catch (ex) {
  531.   }
  532.  
  533.   window.XULBrowserWindow.destroy();
  534.   window.XULBrowserWindow = null;
  535.  
  536.   BrowserFlushBookmarksAndHistory();
  537.  
  538.   // unregister us as a pref listener
  539.   removePrefListener(gButtonPrefListener);
  540.   removePrefListener(gTabStripPrefListener);
  541.  
  542.   window.browserContentListener.close();
  543.   // Close the app core.
  544.   if (appCore)
  545.     appCore.close();
  546. }
  547.  
  548. function Translate()
  549. {
  550.   var service = pref.getCharPref("browser.translation.service");
  551.   var serviceDomain = pref.getCharPref("browser.translation.serviceDomain");
  552.   var targetURI = getWebNavigation().currentURI.spec;
  553.  
  554.   // if we're already viewing a translated page, then just reload
  555.   if (targetURI.indexOf(serviceDomain) >= 0)
  556.     BrowserReload();
  557.   else {
  558.     loadURI(service + escape(targetURI));
  559.   }
  560. }
  561.  
  562. function gotoHistoryIndex(aEvent)
  563. {
  564.   var index = aEvent.target.getAttribute("index");
  565.   if (!index)
  566.     return false;
  567.   try {
  568.     getWebNavigation().gotoIndex(index);
  569.   }
  570.   catch(ex) {
  571.     return false;
  572.   }
  573.   return true;
  574.  
  575. }
  576.  
  577. function BrowserBack()
  578. {
  579.   try {
  580.     getWebNavigation().goBack();
  581.   }
  582.   catch(ex) {
  583.   }
  584. }
  585.  
  586. function BrowserForward()
  587. {
  588.   try {
  589.     getWebNavigation().goForward();
  590.   }
  591.   catch(ex) {
  592.   }
  593. }
  594.  
  595. function BrowserBackMenu(event)
  596. {
  597.   return FillHistoryMenu(event.target, "back");
  598. }
  599.  
  600. function BrowserForwardMenu(event)
  601. {
  602.   return FillHistoryMenu(event.target, "forward");
  603. }
  604.  
  605. function BrowserStop()
  606. {
  607.   try {
  608.     const stopFlags = nsIWebNavigation.STOP_ALL;
  609.     getWebNavigation().stop(stopFlags);
  610.   }
  611.   catch(ex) {
  612.   }
  613. }
  614.  
  615. function BrowserReload()
  616. {
  617.   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_NONE;
  618.   return BrowserReloadWithFlags(reloadFlags);
  619. }
  620.  
  621. function BrowserReloadSkipCache()
  622. {
  623.   // Bypass proxy and cache.
  624.   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
  625.   return BrowserReloadWithFlags(reloadFlags);
  626. }
  627.  
  628. function BrowserHome()
  629. {
  630.   var homePage = getHomePage();
  631.   loadURI(homePage);
  632. }
  633.  
  634. function OpenBookmarkGroup(element, datasource)
  635. {
  636.   if (!datasource)
  637.     return;
  638.  
  639.   var id = element.getAttribute("id");
  640.   var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  641.                           .getService(Components.interfaces.nsIRDFService);
  642.   var resource = rdf.GetResource(id, true);
  643.   return OpenBookmarkGroupFromResource(resource, datasource, rdf);
  644. }
  645.  
  646. function OpenBookmarkGroupFromResource(resource, datasource, rdf) {
  647.   var urlResource = rdf.GetResource("http://home.netscape.com/NC-rdf#URL");
  648.   var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"].getService(Components.interfaces.nsIRDFContainer);
  649.   rdfContainer.Init(datasource, resource);
  650.   var containerChildren = rdfContainer.GetElements();
  651.   var tabPanels = gBrowser.mPanelContainer.childNodes;
  652.   var tabCount = tabPanels.length;
  653.   var index = 0;
  654.   while (containerChildren.hasMoreElements()) {
  655.     var resource = containerChildren.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  656.     var target = datasource.GetTarget(resource, urlResource, true);
  657.     if (target) {
  658.       var uri = target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  659.       if (index < tabCount)
  660.         tabPanels[index].loadURI(uri, null, nsIWebNavigation.LOAD_FLAGS_NONE);
  661.       else
  662.         gBrowser.addTab(uri);
  663.       index++;
  664.     }
  665.   }
  666.  
  667.   if (index == 0)
  668.     return; // If the bookmark group was completely invalid, just bail.
  669.  
  670.   // Select the first tab in the group.
  671.   var tabs = gBrowser.mTabContainer.childNodes;
  672.   gBrowser.selectedTab = tabs[0];
  673.  
  674.   // Close any remaining open tabs that are left over.
  675.   for (var i = tabCount-1; i >= index; i--)
  676.     gBrowser.removeTab(tabs[i]);
  677. }
  678.  
  679. function OpenBookmarkURL(node, datasources)
  680. {
  681.   if (node.getAttribute("group") == "true")
  682.     OpenBookmarkGroup(node, datasources);
  683.  
  684.   if (node.getAttribute("container") == "true")
  685.     return;
  686.  
  687.   var url = node.getAttribute("id");
  688.   if (!url) // if empty url (most likely a normal menu item like "Manage Bookmarks",
  689.     return; // don't bother loading it
  690.   try {
  691.     // add support for IE favorites under Win32, and NetPositive URLs under BeOS
  692.     if (datasources) {
  693.       var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  694.                           .getService(Components.interfaces.nsIRDFService);
  695.       var src = rdf.GetResource(url, true);
  696.       var prop = rdf.GetResource("http://home.netscape.com/NC-rdf#URL", true);
  697.       var target = datasources.GetTarget(src, prop, true);
  698.       if (target) {
  699.         target = target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  700.         if (target)
  701.           url = target;
  702.       }
  703.     }
  704.   } catch (ex) {
  705.     return;
  706.   }
  707.  
  708.   // Ignore "NC:" urls.
  709.   if (url.substring(0, 3) == "NC:")
  710.     return;
  711.  
  712.   // Check if we have a browser window
  713.   if (_content) {
  714.     loadURI(url);
  715.     _content.focus();
  716.   }
  717.   else
  718.     openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
  719. }
  720.  
  721. function addBookmarkAs()
  722. {
  723.   const browsers = gBrowser.browsers;
  724.   if (browsers.length > 1)
  725.     BookmarksUtils.addBookmarkForTabBrowser(gBrowser);
  726.   else
  727.     BookmarksUtils.addBookmarkForBrowser(gBrowser.webNavigation, true);
  728. }
  729.  
  730. function readRDFString(aDS,aRes,aProp)
  731. {
  732.   var n = aDS.GetTarget(aRes, aProp, true);
  733.   return n ? n.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
  734. }
  735.  
  736.  
  737. function ensureDefaultEnginePrefs(aRDF,aDS)
  738. {
  739.   var mPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  740.   var defaultName = mPrefs.getComplexValue("browser.search.defaultenginename", Components.interfaces.nsIPrefLocalizedString).data;
  741.   var kNC_Root = aRDF.GetResource("NC:SearchEngineRoot");
  742.   var kNC_child = aRDF.GetResource("http://home.netscape.com/NC-rdf#child");
  743.   var kNC_Name = aRDF.GetResource("http://home.netscape.com/NC-rdf#Name");
  744.  
  745.   var arcs = aDS.GetTargets(kNC_Root, kNC_child, true);
  746.   while (arcs.hasMoreElements()) {
  747.     var engineRes = arcs.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  748.     var name = readRDFString(aDS, engineRes, kNC_Name);
  749.     if (name == defaultName)
  750.       mPrefs.setCharPref("browser.search.defaultengine", engineRes.Value);
  751.   }
  752. }
  753.  
  754. function ensureSearchPref()
  755. {
  756.   var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  757.   var ds = rdf.GetDataSource("rdf:internetsearch");
  758.   var mPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  759.   kNC_Name = rdf.GetResource("http://home.netscape.com/NC-rdf#Name");
  760.   try {
  761.     defaultEngine = mPrefs.getCharPref("browser.search.defaultengine");
  762.   } catch(ex) {
  763.     ensureDefaultEnginePrefs(rdf, ds);
  764.     defaultEngine = mPrefs.getCharPref("browser.search.defaultengine");
  765.   }
  766. }
  767.  
  768. function getSearchUrl(attr)
  769. {
  770.   var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  771.   var ds = rdf.GetDataSource("rdf:internetsearch");
  772.   var kNC_Root = rdf.GetResource("NC:SearchEngineRoot");
  773.   var mPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  774.   var defaultEngine = mPrefs.getCharPref("browser.search.defaultengine");
  775.   var engineRes = rdf.GetResource(defaultEngine);
  776.   var prop = "http://home.netscape.com/NC-rdf#" + attr;
  777.   var kNC_attr = rdf.GetResource(prop);
  778.   var searchURL = readRDFString(ds, engineRes, kNC_attr);
  779.   return searchURL;
  780. }
  781.  
  782.  
  783. function OpenSearch(tabName, forceDialogFlag, searchStr, newWindowFlag)
  784. {
  785.   //This function needs to be split up someday.
  786.  
  787.   var autoOpenSearchPanel = false;
  788.   var defaultSearchURL = null;
  789.   var fallbackDefaultSearchURL = gNavigatorRegionBundle.getString("fallbackDefaultSearchURL");
  790.   ensureSearchPref()
  791.   //Check to see if search string contains "://" or "ftp." or white space.
  792.   //If it does treat as url and match for pattern
  793.  
  794.   var urlmatch= /(:\/\/|^ftp\.)[^ \S]+$/
  795.   var forceAsURL = urlmatch.test(searchStr);
  796.  
  797.   try {
  798.     autoOpenSearchPanel = pref.getBoolPref("browser.search.opensidebarsearchpanel");
  799.     defaultSearchURL = pref.getComplexValue("browser.search.defaulturl",
  800.                                             Components.interfaces.nsIPrefLocalizedString).data;
  801.   } catch (ex) {
  802.   }
  803.  
  804.   // Fallback to a default url (one that we can get sidebar search results for)
  805.   if (!defaultSearchURL)
  806.     defaultSearchURL = fallbackDefaultSearchURL;
  807.  
  808.   if (!searchStr) {
  809.     loadURI(gNavigatorRegionBundle.getString("otherSearchURL"));
  810.   } else {
  811.  
  812.     //Check to see if location bar field is a url
  813.     //If it is a url go to URL.  A Url is "://" or "." as commented above
  814.     //Otherwise search on entry
  815.     if (forceAsURL) {
  816.        BrowserLoadURL()
  817.     } else {
  818.       var searchMode = 0;
  819.       try {
  820.         searchMode = pref.getIntPref("browser.search.powermode");
  821.       } catch(ex) {
  822.       }
  823.  
  824.       if (forceDialogFlag || searchMode == 1) {
  825.         // Use a single search dialog
  826.         var windowManager = Components.classes["@mozilla.org/rdf/datasource;1?name=window-mediator"]
  827.                                       .getService(Components.interfaces.nsIWindowMediator);
  828.  
  829.         var searchWindow = windowManager.getMostRecentWindow("search:window");
  830.         if (!searchWindow) {
  831.           openDialog("chrome://communicator/content/search/search.xul", "SearchWindow", "dialog=no,close,chrome,resizable", tabName, searchStr);
  832.         } else {
  833.           // Already had one, focus it and load the page
  834.           searchWindow.focus();
  835.  
  836.           if ("loadPage" in searchWindow)
  837.             searchWindow.loadPage(tabName, searchStr);
  838.         }
  839.       } else {
  840.         if (searchStr) {
  841.           var escapedSearchStr = escape(searchStr);
  842.           defaultSearchURL += escapedSearchStr;
  843.           var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
  844.                                    .getService(Components.interfaces.nsIInternetSearchService);
  845.  
  846.           searchDS.RememberLastSearchText(escapedSearchStr);
  847.           try {
  848.             var searchEngineURI = pref.getCharPref("browser.search.defaultengine");
  849.             if (searchEngineURI) {
  850.               var searchURL = getSearchUrl("actionButton");
  851.               if (searchURL) {
  852.                 defaultSearchURL = searchURL + escapedSearchStr;
  853.               } else {
  854.                 searchURL = searchDS.GetInternetSearchURL(searchEngineURI, escapedSearchStr, 0, 0, {value:0});
  855.                 if (searchURL)
  856.                   defaultSearchURL = searchURL;
  857.               }
  858.             }
  859.           } catch (ex) {
  860.           }
  861.  
  862.           if (!newWindowFlag)
  863.             loadURI(defaultSearchURL);
  864.           else
  865.             window.open(defaultSearchURL, "_blank");
  866.         }
  867.       }
  868.     }
  869.   }
  870.  
  871.   // should we try and open up the sidebar to show the "Search Results" panel?
  872.   if (autoOpenSearchPanel)
  873.     RevealSearchPanel();
  874. }
  875.  
  876. function RevealSearchPanel()
  877. {
  878.   var searchPanel = document.getElementById("urn:sidebar:panel:search");
  879.   if (searchPanel)
  880.     SidebarSelectPanel(searchPanel, true, true); // lives in sidebarOverlay.js
  881. }
  882.  
  883. function isSearchPanelOpen()
  884. {
  885.   return ( !sidebar_is_hidden()    &&
  886.            !sidebar_is_collapsed() &&
  887.            SidebarGetLastSelectedPanel() == "urn:sidebar:panel:search"
  888.          );
  889. }
  890.  
  891. //Note: BrowserNewEditorWindow() was moved to globalOverlay.xul and renamed to NewEditorWindow()
  892.  
  893. function BrowserOpenWindow()
  894. {
  895.   //opens a window where users can select a web location to open
  896.   openDialog("chrome://communicator/content/openLocation.xul", "_blank", "chrome,modal,titlebar", window);
  897. }
  898.  
  899. function BrowserOpenTab()
  900. {
  901.   if (!gInPrintPreviewMode) {
  902.     gBrowser.selectedTab = gBrowser.addTab('about:blank');
  903.     setTimeout("gURLBar.focus();", 0);
  904.   }
  905. }
  906.  
  907. /* Called from the openLocation dialog. This allows that dialog to instruct
  908.    its opener to open a new window and then step completely out of the way.
  909.    Anything less byzantine is causing horrible crashes, rather believably,
  910.    though oddly only on Linux. */
  911. function delayedOpenWindow(chrome,flags,url)
  912. {
  913.   setTimeout("openDialog('"+chrome+"','_blank','"+flags+"','"+url+"')", 10);
  914. }
  915.  
  916. /* Required because the tab needs time to set up its content viewers and get the load of
  917.    the URI kicked off before becoming the active content area. */
  918. function delayedOpenTab(url)
  919. {
  920.   setTimeout(function(aTabElt) { getBrowser().selectedTab = aTabElt; }, 0, getBrowser().addTab(url));
  921. }
  922.  
  923. function BrowserOpenFileWindow()
  924. {
  925.   // Get filepicker component.
  926.   try {
  927.     const nsIFilePicker = Components.interfaces.nsIFilePicker;
  928.     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  929.     fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
  930.     fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
  931.                      nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
  932.  
  933.     if (fp.show() == nsIFilePicker.returnOK)
  934.       openTopWin(fp.fileURL.spec);
  935.   } catch (ex) {
  936.   }
  937. }
  938.  
  939. // Set up a lame hack to avoid opening two bookmarks.
  940. // Could otherwise happen with two Ctrl-B's in a row.
  941. var gDisableBookmarks = false;
  942. function enableBookmarks()
  943. {
  944.   gDisableBookmarks = false;
  945. }
  946.  
  947. function BrowserEditBookmarks()
  948. {
  949.   // Use a single sidebar bookmarks dialog
  950.   var windowManager = Components.classes["@mozilla.org/rdf/datasource;1?name=window-mediator"]
  951.                                 .getService(Components.interfaces.nsIWindowMediator);
  952.  
  953.   var bookmarksWindow = windowManager.getMostRecentWindow("bookmarks:manager");
  954.  
  955.   if (bookmarksWindow) {
  956.     bookmarksWindow.focus();
  957.   } else {
  958.     // while disabled, don't open new bookmarks window
  959.     if (!gDisableBookmarks) {
  960.       gDisableBookmarks = true;
  961.  
  962.       open("chrome://communicator/content/bookmarks/bookmarks.xul", "_blank",
  963.         "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
  964.       setTimeout(enableBookmarks, 2000);
  965.     }
  966.   }
  967. }
  968.  
  969. function BrowserCloseTabOrWindow()
  970. {
  971.   var browser = getBrowser();
  972.   if (browser && browser.localName == 'tabbrowser' && browser.mTabContainer.childNodes.length > 1) {
  973.     // Just close up a tab.
  974.     browser.removeCurrentTab();
  975.     return;
  976.   }
  977.  
  978.   BrowserCloseWindow();
  979. }
  980.  
  981. function BrowserCloseWindow()
  982. {
  983.   // This code replicates stuff in Shutdown().  It is here because
  984.   // window.screenX and window.screenY have real values.  We need
  985.   // to fix this eventually but by replicating the code here, we
  986.   // provide a means of saving position (it just requires that the
  987.   // user close the window via File->Close (vs. close box).
  988.  
  989.   // Get the current window position/size.
  990.   var x = window.screenX;
  991.   var y = window.screenY;
  992.   var h = window.outerHeight;
  993.   var w = window.outerWidth;
  994.  
  995.   // Store these into the window attributes (for persistence).
  996.   var win = document.getElementById( "main-window" );
  997.   win.setAttribute( "x", x );
  998.   win.setAttribute( "y", y );
  999.   win.setAttribute( "height", h );
  1000.   win.setAttribute( "width", w );
  1001.  
  1002.   window.close();
  1003. }
  1004.  
  1005. function loadURI(uri, referrer)
  1006. {
  1007.   try {
  1008.     getWebNavigation().loadURI(uri, nsIWebNavigation.LOAD_FLAGS_NONE, referrer, null, null);
  1009.   } catch (e) {
  1010.   }
  1011. }
  1012.  
  1013. function BrowserLoadURL(aTriggeringEvent)
  1014. {
  1015.   var url = gURLBar.value;
  1016.   if (url.match(/^view-source:/)) {
  1017.     BrowserViewSourceOfURL(url.replace(/^view-source:/, ""), null, null);
  1018.   } else {
  1019.     if (pref && pref.getBoolPref("browser.tabs.opentabfor.urlbar") &&
  1020.         getBrowser().localName == "tabbrowser" &&
  1021.         aTriggeringEvent && 'ctrlKey' in aTriggeringEvent &&
  1022.         aTriggeringEvent.ctrlKey) {
  1023.       var t = getBrowser().addTab(getShortcutOrURI(url)); // open link in new tab
  1024.       getBrowser().selectedTab = t;
  1025.     }
  1026.     else
  1027.       loadURI(getShortcutOrURI(url));
  1028.     _content.focus();
  1029.   }
  1030. }
  1031.  
  1032. function getShortcutOrURI(url)
  1033. {
  1034.   // rjc: added support for URL shortcuts (3/30/1999)
  1035.   try {
  1036.     if (!gBookmarksService)
  1037.       gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  1038.                                     .getService(Components.interfaces.nsIBookmarksService);
  1039.  
  1040.     var shortcutURL = gBookmarksService.resolveKeyword(url);
  1041.     if (!shortcutURL) {
  1042.       // rjc: add support for string substitution with shortcuts (4/4/2000)
  1043.       //      (see bug # 29871 for details)
  1044.       var aOffset = url.indexOf(" ");
  1045.       if (aOffset > 0) {
  1046.         var cmd = url.substr(0, aOffset);
  1047.         var text = url.substr(aOffset+1);
  1048.         shortcutURL = gBookmarksService.resolveKeyword(cmd);
  1049.         if (shortcutURL && text) {
  1050.           aOffset = shortcutURL.indexOf("%s");
  1051.           if (aOffset >= 0)
  1052.             shortcutURL = shortcutURL.substr(0, aOffset) + text + shortcutURL.substr(aOffset+2);
  1053.           else
  1054.             shortcutURL = null;
  1055.         }
  1056.       }
  1057.     }
  1058.  
  1059.     if (shortcutURL)
  1060.       url = shortcutURL;
  1061.  
  1062.   } catch (ex) {
  1063.   }
  1064.   return url;
  1065. }
  1066.  
  1067. function readFromClipboard()
  1068. {
  1069.   var url;
  1070.  
  1071.   try {
  1072.     // Get clipboard.
  1073.     var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
  1074.                               .getService(Components.interfaces.nsIClipboard);
  1075.  
  1076.     // Create tranferable that will transfer the text.
  1077.     var trans = Components.classes["@mozilla.org/widget/transferable;1"]
  1078.                           .createInstance(Components.interfaces.nsITransferable);
  1079.  
  1080.     trans.addDataFlavor("text/unicode");
  1081.     clipboard.getData(trans, clipboard.kSelectionClipboard);
  1082.  
  1083.     var data = {};
  1084.     var dataLen = {};
  1085.     trans.getTransferData("text/unicode", data, dataLen);
  1086.  
  1087.     if (data) {
  1088.       data = data.value.QueryInterface(Components.interfaces.nsISupportsWString);
  1089.       url = data.data.substring(0, dataLen.value / 2);
  1090.     }
  1091.   } catch (ex) {
  1092.   }
  1093.  
  1094.   return url;
  1095. }
  1096.  
  1097. function OpenMessenger()
  1098. {
  1099.   open("chrome://messenger/content/messenger.xul", "_blank",
  1100.     "chrome,extrachrome,menubar,resizable,status,toolbar");
  1101. }
  1102.  
  1103. function OpenAddressbook()
  1104. {
  1105.   open("chrome://messenger/content/addressbook/addressbook.xul", "_blank",
  1106.     "chrome,extrachrome,menubar,resizable,status,toolbar");
  1107. }
  1108.  
  1109. function BrowserViewSourceOfDocument(aDocument)
  1110. {
  1111.   var docCharset;
  1112.   var pageCookie;
  1113.   var webNav;
  1114.  
  1115.   // Get the document charset
  1116.   docCharset = "charset=" + aDocument.characterSet;
  1117.  
  1118.   // Get the nsIWebNavigation associated with the document
  1119.   try {
  1120.       var win;
  1121.       var ifRequestor;
  1122.  
  1123.       // Get the DOMWindow for the requested document.  If the DOMWindow
  1124.       // cannot be found, then just use the _content window...
  1125.       //
  1126.       // XXX:  This is a bit of a hack...
  1127.       win = aDocument.defaultView;
  1128.       if (win == window) {
  1129.         win = _content;
  1130.       }
  1131.       ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  1132.  
  1133.       webNav = ifRequestor.getInterface(Components.interfaces.nsIWebNavigation);
  1134.   } catch(err) {
  1135.       // If nsIWebNavigation cannot be found, just get the one for the whole
  1136.       // window...
  1137.       webNav = getWebNavigation();
  1138.   }
  1139.   //
  1140.   // Get the 'PageDescriptor' for the current document. This allows the
  1141.   // view-source to access the cached copy of the content rather than
  1142.   // refetching it from the network...
  1143.   //
  1144.   try{
  1145.     var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor);
  1146.  
  1147.     pageCookie = PageLoader.currentDescriptor;
  1148.   } catch(err) {
  1149.     // If no page descriptor is available, just use the view-source URL...
  1150.   }
  1151.  
  1152.   BrowserViewSourceOfURL(webNav.currentURI.spec, docCharset, pageCookie);
  1153. }
  1154.  
  1155. function BrowserViewSourceOfURL(url, charset, pageCookie)
  1156. {
  1157.   // try to open a view-source window while inheriting the charset (if any)
  1158.   openDialog("chrome://navigator/content/viewSource.xul",
  1159.              "_blank",
  1160.              "scrollbars,resizable,chrome,dialog=no",
  1161.              url, charset, pageCookie);
  1162. }
  1163.  
  1164. // doc=null for regular page info, doc=owner document for frame info.
  1165. function BrowserPageInfo(doc)
  1166. {
  1167.   window.openDialog("chrome://navigator/content/pageInfo.xul",
  1168.                     "_blank",
  1169.                     "chrome,dialog=no",
  1170.                     doc);
  1171. }
  1172.  
  1173. function hiddenWindowStartup()
  1174. {
  1175.   // focus the hidden window
  1176.   window.focus();
  1177.  
  1178.   // Disable menus which are not appropriate
  1179.   var disabledItems = ['cmd_close', 'Browser:SendPage', 'Browser:EditPage', 'Browser:PrintSetup', /*'Browser:PrintPreview',*/
  1180.                        'Browser:Print', 'canGoBack', 'canGoForward', 'Browser:Home', 'Browser:AddBookmark', 'cmd_undo',
  1181.                        'cmd_redo', 'cmd_cut', 'cmd_copy','cmd_paste', 'cmd_delete', 'cmd_selectAll', 'menu_textZoom'];
  1182.   for (var id in disabledItems) {
  1183.     var broadcaster = document.getElementById(disabledItems[id]);
  1184.     if (broadcaster)
  1185.       broadcaster.setAttribute("disabled", "true");
  1186.   }
  1187. }
  1188.  
  1189. // Initialize the LeakDetector class.
  1190. function LeakDetector(verbose)
  1191. {
  1192.   this.verbose = verbose;
  1193. }
  1194.  
  1195. const NS_LEAKDETECTOR_CONTRACTID = "@mozilla.org/xpcom/leakdetector;1";
  1196.  
  1197. if (NS_LEAKDETECTOR_CONTRACTID in Components.classes) {
  1198.   try {
  1199.     LeakDetector.prototype = Components.classes[NS_LEAKDETECTOR_CONTRACTID]
  1200.                                        .createInstance(Components.interfaces.nsILeakDetector);
  1201.   } catch (err) {
  1202.     LeakDetector.prototype = Object.prototype;
  1203.   }
  1204. } else {
  1205.   LeakDetector.prototype = Object.prototype;
  1206. }
  1207.  
  1208. var leakDetector = new LeakDetector(false);
  1209.  
  1210. // Dumps current set of memory leaks.
  1211. function dumpMemoryLeaks()
  1212. {
  1213.   leakDetector.dumpLeaks();
  1214. }
  1215.  
  1216. // Traces all objects reachable from the chrome document.
  1217. function traceChrome()
  1218. {
  1219.   leakDetector.traceObject(document, leakDetector.verbose);
  1220. }
  1221.  
  1222. // Traces all objects reachable from the content document.
  1223. function traceDocument()
  1224. {
  1225.   // keep the chrome document out of the dump.
  1226.   leakDetector.markObject(document, true);
  1227.   leakDetector.traceObject(_content, leakDetector.verbose);
  1228.   leakDetector.markObject(document, false);
  1229. }
  1230.  
  1231. // Controls whether or not we do verbose tracing.
  1232. function traceVerbose(verbose)
  1233. {
  1234.   leakDetector.verbose = (verbose == "true");
  1235. }
  1236.  
  1237. var consoleListener = {
  1238.   observe: function (aMsgObject)
  1239.   {
  1240.     const nsIScriptError = Components.interfaces.nsIScriptError;
  1241.     var scriptError = aMsgObject.QueryInterface(nsIScriptError);
  1242.     var isWarning = scriptError.flags & nsIScriptError.warningFlag != 0;
  1243.     if (!isWarning) {
  1244.       var statusbarDisplay = document.getElementById("statusbar-display");
  1245.       statusbarDisplay.setAttribute("error", "true");
  1246.       statusbarDisplay.addEventListener("click", loadErrorConsole, true);
  1247.       statusbarDisplay.label = gNavigatorBundle.getString("jserror");
  1248.       this.isShowingError = true;
  1249.     }
  1250.   },
  1251.  
  1252.   // whether or not an error alert is being displayed
  1253.   isShowingError: false
  1254. };
  1255.  
  1256. function initConsoleListener()
  1257. {
  1258.   /**
  1259.    * XXX - console launch hookup requires some work that I'm not sure
  1260.    * how to do.
  1261.    *
  1262.    *       1) ideally, the notification would disappear when the
  1263.    *       document that had the error was flushed. how do I know when
  1264.    *       this happens? All the nsIScriptError object I get tells me
  1265.    *       is the URL. Where is it located in the content area?
  1266.    *       2) the notification service should not display chrome
  1267.    *       script errors.  web developers and users are not interested
  1268.    *       in the failings of our shitty, exception unsafe js. One
  1269.    *       could argue that this should also extend to the console by
  1270.    *       default (although toggle-able via setting for chrome
  1271.    *       authors) At any rate, no status indication should be given
  1272.    *       for chrome script errors.
  1273.    *
  1274.    *       As a result I am commenting out this for the moment.
  1275.    *
  1276.  
  1277.   var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  1278.                                  .getService(Components.interfaces.nsIConsoleService);
  1279.  
  1280.   if (consoleService)
  1281.     consoleService.registerListener(consoleListener);
  1282.   */
  1283. }
  1284.  
  1285. function loadErrorConsole(aEvent)
  1286. {
  1287.   if (aEvent.detail == 2)
  1288.     toJavaScriptConsole();
  1289. }
  1290.  
  1291. function clearErrorNotification()
  1292. {
  1293.   var statusbarDisplay = document.getElementById("statusbar-display");
  1294.   statusbarDisplay.removeAttribute("error");
  1295.   statusbarDisplay.removeEventListener("click", loadErrorConsole, true);
  1296.   consoleListener.isShowingError = false;
  1297. }
  1298.  
  1299. const NS_URLWIDGET_CONTRACTID = "@mozilla.org/urlwidget;1";
  1300. var urlWidgetService = null;
  1301. if (NS_URLWIDGET_CONTRACTID in Components.classes) {
  1302.   urlWidgetService = Components.classes[NS_URLWIDGET_CONTRACTID]
  1303.                                .getService(Components.interfaces.nsIUrlWidget);
  1304. }
  1305.  
  1306. //Posts the currently displayed url to a native widget so third-party apps can observe it.
  1307. function postURLToNativeWidget()
  1308. {
  1309.   if (urlWidgetService) {
  1310.     var url = getWebNavigation().currentURI.spec;
  1311.     try {
  1312.       urlWidgetService.SetURLToHiddenControl(url, window);
  1313.     } catch(ex) {
  1314.     }
  1315.   }
  1316. }
  1317.  
  1318. function checkForDirectoryListing()
  1319. {
  1320.   if ( "HTTPIndex" in _content &&
  1321.        _content.HTTPIndex instanceof Components.interfaces.nsIHTTPIndex ) {
  1322.     _content.defaultCharacterset = getMarkupDocumentViewer().defaultCharacterSet;
  1323.   }
  1324. }
  1325.  
  1326. /**
  1327.  * Use Stylesheet functions.
  1328.  *     Written by Tim Hill (bug 6782)
  1329.  *     Frameset handling by Neil Rashbrook <neil@parkwaycc.co.uk>
  1330.  **/
  1331. function getStyleSheetArray(frame)
  1332. {
  1333.   var styleSheets = frame.document.styleSheets;
  1334.   var styleSheetsArray = new Array(styleSheets.length);
  1335.   for (var i = 0; i < styleSheets.length; i++) {
  1336.     styleSheetsArray[i] = styleSheets[i];
  1337.   }
  1338.   return styleSheetsArray;
  1339. }
  1340.  
  1341. function getAllStyleSheets(frameset)
  1342. {
  1343.   var styleSheetsArray = getStyleSheetArray(frameset);
  1344.   for (var i = 0; i < frameset.frames.length; i++) {
  1345.     var frameSheets = getAllStyleSheets(frameset.frames[i]);
  1346.     styleSheetsArray = styleSheetsArray.concat(frameSheets);
  1347.   }
  1348.   return styleSheetsArray;
  1349. }
  1350.  
  1351. function stylesheetFillPopup(menuPopup)
  1352. {
  1353.   var itemNoOptStyles = menuPopup.firstChild;
  1354.   while (itemNoOptStyles.nextSibling)
  1355.     menuPopup.removeChild(itemNoOptStyles.nextSibling);
  1356.  
  1357.   var noOptionalStyles = true;
  1358.   var styleSheets = getAllStyleSheets(window._content);
  1359.   var currentStyleSheets = [];
  1360.  
  1361.   for (var i = 0; i < styleSheets.length; ++i) {
  1362.     var currentStyleSheet = styleSheets[i];
  1363.  
  1364.     if (currentStyleSheet.title) {
  1365.       if (!currentStyleSheet.disabled)
  1366.         noOptionalStyles = false;
  1367.  
  1368.       var lastWithSameTitle = null;
  1369.       if (currentStyleSheet.title in currentStyleSheets)
  1370.         lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
  1371.  
  1372.       if (!lastWithSameTitle) {
  1373.         var menuItem = document.createElement("menuitem");
  1374.         menuItem.setAttribute("type", "radio");
  1375.         menuItem.setAttribute("label", currentStyleSheet.title);
  1376.         menuItem.setAttribute("data", currentStyleSheet.title);
  1377.         menuItem.setAttribute("checked", !currentStyleSheet.disabled);
  1378.         menuPopup.appendChild(menuItem);
  1379.         currentStyleSheets[currentStyleSheet.title] = menuItem;
  1380.       } else {
  1381.         if (currentStyleSheet.disabled)
  1382.           lastWithSameTitle.removeAttribute("checked");
  1383.       }
  1384.     }
  1385.   }
  1386.   itemNoOptStyles.setAttribute("checked", noOptionalStyles);
  1387. }
  1388.  
  1389. function stylesheetInFrame(frame, title) {
  1390.   var docStyleSheets = frame.document.styleSheets;
  1391.  
  1392.   for (var i = 0; i < docStyleSheets.length; ++i) {
  1393.     if (docStyleSheets[i].title == title)
  1394.       return true;
  1395.   }
  1396.   return false;
  1397. }
  1398.  
  1399. function stylesheetSwitchFrame(frame, title) {
  1400.   var docStyleSheets = frame.document.styleSheets;
  1401.  
  1402.   for (var i = 0; i < docStyleSheets.length; ++i) {
  1403.     var docStyleSheet = docStyleSheets[i];
  1404.  
  1405.     if (docStyleSheet.title)
  1406.       docStyleSheet.disabled = (docStyleSheet.title != title);
  1407.     else if (docStyleSheet.disabled)
  1408.       docStyleSheet.disabled = false;
  1409.   }
  1410. }
  1411.  
  1412. function stylesheetSwitchAll(frameset, title) {
  1413.   if (!title || stylesheetInFrame(frameset, title)) {
  1414.     stylesheetSwitchFrame(frameset, title);
  1415.   }
  1416.   for (var i = 0; i < frameset.frames.length; i++) {
  1417.     stylesheetSwitchAll(frameset.frames[i], title);
  1418.   }
  1419. }
  1420.  
  1421. function applyTheme(themeName)
  1422. {
  1423.   var name = themeName.getAttribute("name");
  1424.   if (!name)
  1425.     return;
  1426.  
  1427.   var chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
  1428.     .getService(Components.interfaces.nsIChromeRegistry);
  1429.  
  1430.   var oldTheme = false;
  1431.   try {
  1432.     oldTheme = !chromeRegistry.checkThemeVersion(name);
  1433.   }
  1434.   catch(e) {
  1435.   }
  1436.  
  1437.   var str = Components.classes["@mozilla.org/supports-wstring;1"]
  1438.                       .createInstance(Components.interfaces.nsISupportsWString);
  1439.  
  1440.   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  1441.   if (oldTheme) {
  1442.     var title = gNavigatorBundle.getString("oldthemetitle");
  1443.     var message = gNavigatorBundle.getString("oldTheme");
  1444.  
  1445.     message = message.replace(/%theme_name%/, themeName.getAttribute("displayName"));
  1446.     message = message.replace(/%brand%/g, gBrandBundle.getString("brandShortName"));
  1447.  
  1448.     if (promptService.confirm(window, title, message)){
  1449.       var inUse = chromeRegistry.isSkinSelected(name, true);
  1450.  
  1451.       chromeRegistry.uninstallSkin( name, true );
  1452.       // XXX - this sucks and should only be temporary.
  1453.  
  1454.       str.data = true;
  1455.       pref.setComplexValue("general.skins.removelist." + name,
  1456.                            Components.interfaces.nsISupportsWString, str);
  1457.  
  1458.       if (inUse)
  1459.         chromeRegistry.refreshSkins();
  1460.     }
  1461.  
  1462.     return;
  1463.   }
  1464.  
  1465.  // XXX XXX BAD BAD BAD BAD !! XXX XXX
  1466.  // we STILL haven't fixed editor skin switch problems
  1467.  // hacking around it yet again
  1468.  
  1469.  str.data = themeName.getAttribute("name");
  1470.  pref.setComplexValue("general.skins.selectedSkin", Components.interfaces.nsISupportsWString, str);
  1471.  
  1472.  // shut down quicklaunch so the next launch will have the new skin
  1473.  var appShell = Components.classes['@mozilla.org/appshell/appShellService;1'].getService();
  1474.  appShell = appShell.QueryInterface(Components.interfaces.nsIAppShellService);
  1475.  try {
  1476.    appShell.nativeAppSupport.isServerMode = false;
  1477.  }
  1478.  catch(ex) {
  1479.  }
  1480.  
  1481.  if (promptService) {
  1482.    var dialogTitle = gNavigatorBundle.getString("switchskinstitle");
  1483.    var brandName = gBrandBundle.getString("brandShortName");
  1484.    var msg = gNavigatorBundle.getFormattedString("switchskins", [brandName]);
  1485.    promptService.alert(window, dialogTitle, msg);
  1486.  }
  1487. }
  1488.  
  1489. function getNewThemes()
  1490. {
  1491.   loadURI(gBrandRegionBundle.getString("getNewThemesURL"));
  1492. }
  1493.  
  1494. function URLBarFocusHandler(aEvent)
  1495. {
  1496.   if (gURLBar) {
  1497.     if (gClickSelectsAll == -1)
  1498.       gClickSelectsAll = pref.getBoolPref("browser.urlbar.clickSelectsAll");
  1499.     if (gClickSelectsAll)
  1500.       gURLBar.setSelectionRange(0, gURLBar.textLength);
  1501.   }
  1502. }
  1503.  
  1504. function URLBarBlurHandler(aEvent)
  1505. {
  1506.   // XXX why the hell do we have to do this?
  1507.   if (gClickSelectsAll)
  1508.     gURLBar.setSelectionRange(0, 0);
  1509. }
  1510.  
  1511. function URLBarKeyupHandler(aEvent)
  1512. {
  1513.   if (aEvent.keyCode == aEvent.DOM_VK_TAB ) {
  1514.     ShowAndSelectContentsOfURLBar();
  1515.   }
  1516. }
  1517.  
  1518. // This function gets the "windows hooks" service and has it check its setting
  1519. // This will do nothing on platforms other than Windows.
  1520. function checkForDefaultBrowser()
  1521. {
  1522.   const NS_WINHOOKS_CONTRACTID = "@mozilla.org/winhooks;1";
  1523.   var dialogShown = false;
  1524.   if (NS_WINHOOKS_CONTRACTID in Components.classes) {
  1525.     try {
  1526.       dialogShown = Components.classes[NS_WINHOOKS_CONTRACTID]
  1527.                       .getService(Components.interfaces.nsIWindowsHooks)
  1528.                       .checkSettings(window);
  1529.     } catch(e) {
  1530.     }
  1531.  
  1532.     if (dialogShown)
  1533.     {
  1534.       // Force the sidebar to build since the windows
  1535.       // integration dialog may have come up.
  1536.       SidebarRebuild();
  1537.     }
  1538.   }
  1539. }
  1540.  
  1541. function ShowAndSelectContentsOfURLBar()
  1542. {
  1543.   var navBar = document.getElementById("nav-bar");
  1544.  
  1545.   // If it's hidden, show it.
  1546.   if (navBar.getAttribute("hidden") == "true")
  1547.     goToggleToolbar('nav-bar','cmd_viewnavbar');
  1548.  
  1549.   if (gURLBar.value)
  1550.     gURLBar.select();
  1551.   else
  1552.     gURLBar.focus();
  1553. }
  1554.  
  1555. // If "ESC" is pressed in the url bar, we replace the urlbar's value with the url of the page
  1556. // and highlight it, unless it is about:blank, where we reset it to "".
  1557. function handleURLBarRevert()
  1558. {
  1559.   var url = getWebNavigation().currentURI.spec;
  1560.   var throbberElement = document.getElementById("navigator-throbber");
  1561.  
  1562.   var isScrolling = gURLBar.userAction == "scrolling";
  1563.  
  1564.   // don't revert to last valid url unless page is NOT loading
  1565.   // and user is NOT key-scrolling through autocomplete list
  1566.   if (!throbberElement.hasAttribute("busy") && !isScrolling) {
  1567.     if (url != "about:blank") {
  1568.       gURLBar.value = url;
  1569.       gURLBar.select();
  1570.       SetPageProxyState("valid", null); // XXX Build a URI and pass it in here.
  1571.     } else { //if about:blank, urlbar becomes ""
  1572.       gURLBar.value = "";
  1573.     }
  1574.   }
  1575.  
  1576.   // tell widget to revert to last typed text only if the user
  1577.   // was scrolling when they hit escape
  1578.   return isScrolling;
  1579. }
  1580.  
  1581. function handleURLBarCommand(aUserAction, aTriggeringEvent)
  1582. {
  1583.   try {
  1584.     addToUrlbarHistory();
  1585.   } catch (ex) {
  1586.     // Things may go wrong when adding url to session history,
  1587.     // but don't let that interfere with the loading of the url.
  1588.   }
  1589.  
  1590.   BrowserLoadURL(aTriggeringEvent);
  1591. }
  1592.  
  1593. function UpdatePageProxyState()
  1594. {
  1595.   if (gURLBar.value != gLastValidURLStr)
  1596.     SetPageProxyState("invalid", null);
  1597. }
  1598.  
  1599. function SetPageProxyState(aState, aURI)
  1600. {
  1601.   if (!gProxyButton)
  1602.     gProxyButton = document.getElementById("page-proxy-button");
  1603.   if (!gProxyFavIcon)
  1604.     gProxyFavIcon = document.getElementById("page-proxy-favicon");
  1605.   if (!gProxyDeck)
  1606.     gProxyDeck = document.getElementById("page-proxy-deck");
  1607.  
  1608.   gProxyButton.setAttribute("pageproxystate", aState);
  1609.  
  1610.   if (aState == "valid") {
  1611.     gLastValidURLStr = gURLBar.value;
  1612.     gURLBar.addEventListener("input", UpdatePageProxyState, false);
  1613.     if (gBrowser.shouldLoadFavIcon(aURI)) {
  1614.       var favStr = gBrowser.buildFavIconString(aURI);
  1615.       if (favStr != gProxyFavIcon.src) {
  1616.         gBrowser.loadFavIcon(aURI, "src", gProxyFavIcon);
  1617.         gProxyDeck.selectedIndex = 0;
  1618.       }
  1619.       else gProxyDeck.selectedIndex = 1;
  1620.     }
  1621.     else {
  1622.       gProxyDeck.selectedIndex = 0;
  1623.       gProxyFavIcon.removeAttribute("src");
  1624.     }
  1625.   } else if (aState == "invalid") {
  1626.     gURLBar.removeEventListener("input", UpdatePageProxyState, false);
  1627.     gProxyDeck.selectedIndex = 0;
  1628.   }
  1629. }
  1630.  
  1631. function PageProxyDragGesture(aEvent)
  1632. {
  1633.   if (gProxyButton.getAttribute("pageproxystate") == "valid") {
  1634.     nsDragAndDrop.startDrag(aEvent, proxyIconDNDObserver);
  1635.     return true;
  1636.   }
  1637.   return false;
  1638. }
  1639.  
  1640. function updateComponentBarBroadcaster()
  1641. {
  1642.   var compBarBroadcaster = document.getElementById('cmd_viewcomponentbar');
  1643.   var taskBarBroadcaster = document.getElementById('cmd_viewtaskbar');
  1644.   var compBar = document.getElementById('component-bar');
  1645.   if (taskBarBroadcaster.getAttribute('checked') == 'true') {
  1646.     compBarBroadcaster.removeAttribute('disabled');
  1647.     if (compBar.getAttribute('hidden') != 'true')
  1648.       compBarBroadcaster.setAttribute('checked', 'true');
  1649.   }
  1650.   else {
  1651.     compBarBroadcaster.setAttribute('disabled', 'true');
  1652.     compBarBroadcaster.removeAttribute('checked');
  1653.   }
  1654. }
  1655.  
  1656. function updateToolbarStates(toolbarMenuElt)
  1657. {
  1658.   if (gHaveUpdatedToolbarState) {
  1659.     updateComponentBarBroadcaster();
  1660.     return;
  1661.   }
  1662.   var mainWindow = document.getElementById("main-window");
  1663.   if (mainWindow.hasAttribute("chromehidden")) {
  1664.     gHaveUpdatedToolbarState = true;
  1665.     var i;
  1666.     for (i = 0; i < toolbarMenuElt.childNodes.length; ++i)
  1667.       document.getElementById(toolbarMenuElt.childNodes[i].getAttribute("observes")).removeAttribute("checked");
  1668.     var toolbars = document.getElementsByTagName("toolbar");
  1669.     for (i = 0; i < toolbars.length; ++i) {
  1670.       if (toolbars[i].getAttribute("class").indexOf("chromeclass") != -1)
  1671.         toolbars[i].setAttribute("hidden", "true");
  1672.     }
  1673.     var statusbars = document.getElementsByTagName("statusbar");
  1674.     for (i = 0; i < statusbars.length; ++i) {
  1675.       if (statusbars[i].getAttribute("class").indexOf("chromeclass") != -1)
  1676.         statusbars[i].setAttribute("hidden", "true");
  1677.     }
  1678.     mainWindow.removeAttribute("chromehidden");
  1679.   }
  1680.   updateComponentBarBroadcaster();
  1681. }
  1682.  
  1683. // Fill in tooltips for personal toolbar
  1684. function FillInPTTooltip(tipElement)
  1685. {
  1686.  
  1687.   var title = tipElement.label;
  1688.   var url = tipElement.statusText;
  1689.  
  1690.   if (!title && !url) {
  1691.     // bail out early if there is nothing to show
  1692.     return false;
  1693.   }
  1694.  
  1695.   var tooltipTitle = document.getElementById("ptTitleText");
  1696.   var tooltipUrl = document.getElementById("ptUrlText");
  1697.  
  1698.   if (title && title != url) {
  1699.     tooltipTitle.removeAttribute("hidden");
  1700.     tooltipTitle.setAttribute("value", title);
  1701.   } else  {
  1702.     tooltipTitle.setAttribute("hidden", "true");
  1703.   }
  1704.  
  1705.   if (url) {
  1706.     tooltipUrl.removeAttribute("hidden");
  1707.     tooltipUrl.setAttribute("value", url);
  1708.   } else {
  1709.     tooltipUrl.setAttribute("hidden", "true");
  1710.   }
  1711.  
  1712.   return true; // show tooltip
  1713. }
  1714.  
  1715. function BrowserFullScreen()
  1716. {
  1717.   window.fullScreen = !window.fullScreen;
  1718. }
  1719.  
  1720. function onFullScreen()
  1721. {
  1722.   FullScreen.toggle();
  1723. }
  1724.  
  1725. // Set up a lame hack to avoid opening two bookmarks.
  1726. // Could otherwise happen with two Ctrl-B's in a row.
  1727. var gDisableHistory = false;
  1728. function enableHistory() {
  1729.   gDisableHistory = false;
  1730. }
  1731.  
  1732. function toHistory()
  1733. {
  1734.   // Use a single sidebar history dialog
  1735.  
  1736.   var cwindowManager = Components.classes['@mozilla.org/rdf/datasource;1?name=window-mediator'].getService();
  1737.   var iwindowManager = Components.interfaces.nsIWindowMediator;
  1738.   var windowManager  = cwindowManager.QueryInterface(iwindowManager);
  1739.  
  1740.   var historyWindow = windowManager.getMostRecentWindow('history:manager');
  1741.  
  1742.   if (historyWindow) {
  1743.     //debug("Reuse existing history window");
  1744.     historyWindow.focus();
  1745.   } else {
  1746.     //debug("Open a new history dialog");
  1747.  
  1748.     if (true == gDisableHistory) {
  1749.       //debug("Recently opened one. Wait a little bit.");
  1750.       return;
  1751.     }
  1752.     gDisableHistory = true;
  1753.  
  1754.     window.open( "chrome://communicator/content/history/history.xul", "_blank",
  1755.         "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar" );
  1756.     setTimeout(enableHistory, 2000);
  1757.   }
  1758.  
  1759. }
  1760.  
  1761.  
  1762.